package cn.com.cifi.mars.util;

import cn.com.cifi.mars.entity.PriceApprovalDifferencesDetail;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

/**
 * 类名称：NewAllgoodsValueDetailTemplate
 * 类描述：导出货值差异详情表
 *
 * @author yanboliu
 * @version 1.0.0
 */
@Slf4j
public class NewAllgoodsValueDetailTemplate {
    /**
     * 表格模板地址
     */
    private static final String TEMPLATE_PATH = "/template/new_all_goods_value_detail_template.xlsx";
    /**
     * 初始化文件
     */
    private XSSFWorkbook workbook;
    /**
     * 初始化表格
     */
    private XSSFSheet sheet;
    /**
     * 默认sheet索引
     */
    private int defaultSheetIndex = 0;
    /**
     * 数据开始行
     */
    private int dataBeginRow = 3;
    /**
     * 当前行标
     */
    private int currentDataRowCursor = dataBeginRow;
    /**
     * 单元格样式
     */
    private XSSFCellStyle cellStyle;
    /**
     * 文字样式1
     */
    private XSSFCellStyle cellStyle1;
    /**
     * 文字样式2
     */
    private XSSFCellStyle cellStyle2;
    /**
     * 文字样式3
     */
    private XSSFCellStyle cellStyle3;
    /**
     * 文字样式4
     */
    private XSSFCellStyle cellStyle4;

    /**
     * 设置表格基本属性
     */
    public NewAllgoodsValueDetailTemplate(String name) {

        try {
            InputStream tempInputStream = NewAllGoodsValueReviewTemplate.class.getResourceAsStream(TEMPLATE_PATH);
            if (tempInputStream != null) {
                workbook = new XSSFWorkbook(tempInputStream);
                sheet = workbook.getSheetAt(defaultSheetIndex);
                XSSFRow row = sheet.getRow(dataBeginRow);
                cellStyle1 = sheet.getRow(3).getCell(0).getCellStyle();
                cellStyle2 = sheet.getRow(3).getCell(6).getCellStyle();
                cellStyle3 = sheet.getRow(3).getCell(8).getCellStyle();
                cellStyle4 = sheet.getRow(3).getCell(23).getCellStyle();

            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }


    /**
     * 批量插入行
     */
    public synchronized void appendRows(List<PriceApprovalDifferencesDetail> detailList, int sheetIndex, String projectCode) {
        sheet = workbook.getSheetAt(sheetIndex);
        this.currentDataRowCursor = dataBeginRow;
        detailList.forEach(entity -> {
            if (StringUtils.isEmpty(entity.getProjectCode())) {
                entity.setProjectCode(projectCode);
            }
            this.appendRow(entity);
        });
    }

    /**
     * 插入行
     */
    public synchronized void appendRow(PriceApprovalDifferencesDetail detail) {
        XSSFRow row = sheet.getRow(currentDataRowCursor);
        if (row == null) {
            row = sheet.createRow(currentDataRowCursor);
        }
        int index = 0;
        cellStyle = cellStyle1;
        //基本信息
        this.appendCell(row, index++, detail.getProjectName());
        this.appendCell(row, index++, detail.getProjectCode());
        this.appendCell(row, index++, detail.getStageName());
        this.appendCell(row, index++, detail.getStageCode());
        this.appendCell(row, index++, detail.getGroupName());
        if (StringUtils.isNotEmpty(detail.getProductName())) {
            this.appendCell(row, index++, detail.getProductName()
                    .concat("+").concat(detail.getBusinessTypeName())
                    .concat("+").concat(detail.getFreeTypeName())
                    .concat("+").concat(detail.getProTypeName()));
        } else {
            this.appendCell(row, index++, " ");
        }

        cellStyle = cellStyle2;
        //调整后货值
        this.appendCell(row, index++, detail.getAfterRoomNum());
        this.appendCell(row, index++, detail.getAfterParkingNum());
        cellStyle = cellStyle3;
        this.appendCell(row, index++, modifyDouble(detail.getAfterRoomArea()));

        cellStyle = cellStyle2;
        this.appendCell(row, index++, modifyMathAround(detail.getAfterRoomAvg()));
        this.appendCell(row, index++, modifyMathAround(detail.getAfterParkingAvg()));

        String param1 = null;
        String param2 = null;
        param1 = StringUtils.isEmpty(detail.getAfterRoomPrice()) || StringUtils.equalsIgnoreCase(detail.getAfterRoomPrice(), "null") ? "0" : detail.getAfterRoomPrice();
        param2 = StringUtils.isEmpty(detail.getAfterParkingPrice()) || StringUtils.equalsIgnoreCase(detail.getAfterParkingPrice(), "null") ? "0" : detail.getAfterParkingPrice();
        this.appendCell(row, index++, Math.round((Double.parseDouble(param1)) + Double.parseDouble(param2)) / 10000);
        this.appendCell(row, index++, modifyMathAround2(detail.getAfterRoomPrice()));
        this.appendCell(row, index++, modifyMathAround2(detail.getAfterParkingPrice()));

        //调整前货值
        this.appendCell(row, index++, detail.getVsRoomNum());
        this.appendCell(row, index++, detail.getVsParkingNum());
        cellStyle = cellStyle3;
        this.appendCell(row, index++, modifyDouble(detail.getVsRoomArea()));
        cellStyle = cellStyle2;
        this.appendCell(row, index++, modifyMathAround(detail.getVsRoomAvg()));
        this.appendCell(row, index++, modifyMathAround(detail.getVsParkingAvg()));

        param1 = StringUtils.isEmpty(detail.getVsRoomPrice()) || StringUtils.equalsIgnoreCase(detail.getVsRoomPrice(), "null") ? "0" : detail.getVsRoomPrice();
        param2 = StringUtils.isEmpty(detail.getVsParkingPrice()) || StringUtils.equalsIgnoreCase(detail.getVsParkingPrice(), "null") ? "0" : detail.getVsParkingPrice();
        this.appendCell(row, index++, Math.round((Double.parseDouble(param1) + Double.parseDouble(param2)) / 10000));
        this.appendCell(row, index++, modifyMathAround2(detail.getVsRoomPrice()));
        this.appendCell(row, index++, modifyMathAround2(detail.getVsParkingPrice()));

        //货值差异
        this.appendCell(row, index++, modifyMathAround2(detail.getTotalDiff()));
        this.appendCell(row, index++, modifyPercentage(detail.getTotalDiffPer()));
        this.appendCell(row, index++, modifyMathAround2(detail.getRoomPriceDiff()));
        this.appendCell(row, index++, modifyPercentage(detail.getRoomPriceDiffPer()));
        this.appendCell(row, index++, modifyMathAround(detail.getRoomAvgDiff()));
        this.appendCell(row, index++, modifyPercentage(detail.getRoomAvgDiffPer()));
        cellStyle = cellStyle3;
        this.appendCell(row, index++, modifyDouble(detail.getRoomAreaDiff()));
        cellStyle = cellStyle2;
        this.appendCell(row, index++, modifyPercentage(detail.getRoomAreaDiffPer()));
        this.appendCell(row, index++, detail.getRoomNumDiff());
        this.appendCell(row, index++, modifyPercentage(detail.getRoomNumDiffPer()));
        this.appendCell(row, index++, modifyMathAround2(detail.getParkingPriceDiff()));
        this.appendCell(row, index++, modifyPercentage(detail.getParkingPriceDiffPer()));
        this.appendCell(row, index++, modifyMathAround(detail.getParkingAvgDiff()));
        this.appendCell(row, index++, modifyPercentage(detail.getParkingAvgDiffPer()));
        this.appendCell(row, index++, detail.getParkingNumDiff());
        this.appendCell(row, index++, modifyPercentage(detail.getParkingNumDiffPer()));
        currentDataRowCursor++;

    }

    /**
     * 保留两位小数
     *
     * @param value
     * @return
     */
    private String modifyDouble(String value) {
        String defaultValue = "null";
        if (StringUtils.equalsIgnoreCase(defaultValue, value) || StringUtils.isEmpty(value)) {
            value = defaultValue;
        } else {
            value = String.format("%.2f", Double.parseDouble(value));
        }
        return value;
    }

    /**
     * 四舍五入
     *
     * @param value
     * @return
     */
    private String modifyMathAround(String value) {
        String defaultValue = "null";
        if (StringUtils.equalsIgnoreCase(defaultValue, value) || StringUtils.isEmpty(value)) {
            value = defaultValue;
        } else {
            value = String.valueOf(Math.round(Double.parseDouble(value)));
        }
        return value;
    }

    /**
     * 四舍五入，单位换算为万
     *
     * @param value
     * @return
     */
    private String modifyMathAround2(String value) {
        String defaultValue = "null";
        if (StringUtils.equalsIgnoreCase(defaultValue, value) || StringUtils.isEmpty(value)) {
            value = defaultValue;
        } else {
            value = String.valueOf(Math.round(Double.parseDouble(value) / 10000));
        }
        return value;
    }

    /**
     * 编辑数据至百分数
     *
     * @param value
     * @return
     */
    private String modifyPercentage(String value) {
        String defaultValue = "null";
        if (StringUtils.equalsIgnoreCase(defaultValue, value) || StringUtils.isEmpty(value)) {
            value = defaultValue;
        } else {
            value = String.format("%.2f", Double.parseDouble(value) * 100).concat("%");
        }
        return value;
    }

    /**
     * 插入列
     *
     * @param row
     * @param index
     * @param value
     */
    public synchronized void appendCell(XSSFRow row, int index, String value) {
        String divisionSign = "%";
        XSSFCell cell = row.getCell(index);
        if (cell == null) {
            cell = row.createCell(index);
        }
        cell.setCellStyle(cellStyle);
        if (StringUtils.isNotBlank(value) && value.endsWith(divisionSign)) {
            cell.setCellStyle(cellStyle4);
            cell.setCellValue(value == null || StringUtils.equals(value, "null") ? " " : value);
        } else {
            ReportUtils.setCellValue(cell, value == null || StringUtils.equals(value, "null") ? " " : value);
        }

    }

    /**
     * 插入列
     *
     * @param row
     * @param index
     * @param integer
     */
    public synchronized void appendCell(XSSFRow row, int index, Integer integer) {
        String divisionSign = "%";
        XSSFCell cell = row.getCell(index);
        if (cell == null) {
            cell = row.createCell(index);
        }
        cell.setCellStyle(cellStyle);
        String value = String.valueOf(integer);
        if (StringUtils.isNotBlank(value) && value.endsWith(divisionSign)) {
            cell.setCellStyle(cellStyle4);
            cell.setCellValue(value == null || StringUtils.equals(value, "null") ? " " : value);
        } else {
            ReportUtils.setCellValue(cell, value == null || StringUtils.equals(value, "null") ? " " : value);
        }
    }

    /**
     * 插入列
     *
     * @param row
     * @param index
     * @param d
     */
    public synchronized void appendCell(XSSFRow row, int index, Double d) {
        String divisionSign = "%";
        XSSFCell cell = row.getCell(index);
        if (cell == null) {
            cell = row.createCell(index);
        }
        cell.setCellStyle(cellStyle);
        String value = String.valueOf(d);
        if (StringUtils.isNotBlank(value) && value.endsWith(divisionSign)) {
            cell.setCellStyle(cellStyle4);
            cell.setCellValue(value == null || StringUtils.equals(value, "null") ? " " : value);
        } else {
            ReportUtils.setCellValue(cell, value == null || StringUtils.equals(value, "null") ? " " : value);
        }
    }

    /**
     * 插入列
     *
     * @param row
     * @param index
     * @param l
     */
    public synchronized void appendCell(XSSFRow row, int index, Long l) {
        String divisionSign = "%";
        XSSFCell cell = row.getCell(index);
        if (cell == null) {
            cell = row.createCell(index);
        }
        cell.setCellStyle(cellStyle);
        String value = String.valueOf(l);
        if (StringUtils.isNotBlank(value) && value.endsWith(divisionSign)) {
            cell.setCellStyle(cellStyle4);
            cell.setCellValue(value == null || StringUtils.equals(value, "null") ? " " : value);
        } else {
            ReportUtils.setCellValue(cell, value == null || StringUtils.equals(value, "null") ? " " : value);
        }
    }


    /**
     * 导出
     *
     * @param outputStream
     * @throws IOException
     */
    public void write(OutputStream outputStream) throws IOException {
        workbook.write(outputStream);
    }
}
